package services;

import dao.UserJpaController;
import dao.exceptions.NonexistentEntityException;
import entities.Contest;
import entities.User;
import exceptions.DatabaseException;
import exceptions.NonExistentObjectException;
import exceptions.PreexistingObjectException;
import java.util.ArrayList;
import java.util.List;
import util.EnumSearchParameter;
import vo.VOUser;

/**
 *
 * @author sbaldrich
 */
public class UserService {

    private static UserJpaController uc;

    public static UserJpaController getInstance() {
        if (uc == null) {
            uc = new UserJpaController();
        }
        return uc;
    }
    private static ContestService cs;

    private static ContestService getContestService() {
        if (cs == null) {
            cs = new ContestService();
        }
        return cs;
    }

    public void save(VOUser vo) throws Exception {
        uc = getInstance();
        if (find(vo.getHandle()) != null) {
            throw new PreexistingObjectException("User Handle");
        }
        User u = new User(vo);
        u.setIsAdmin(false);
        try {
            uc.create(u);
        } catch (Exception e) {
            System.out.println("Exception at UserService.save: " + e.getMessage());
            throw new DatabaseException();
        }
    }

    public VOUser find(String handle) throws Exception {
        uc = getInstance();
        try {
            return uc.findUser(handle).getVO();
        } catch (Exception e) {
            return null;
        }
    }

    public User findObject(String handle) throws Exception {
        uc = getInstance();
        try {
            return uc.findUser(handle);
        } catch (Exception e) {
            return null;
        }
    }

    public void update(VOUser vo) throws Exception {
        uc = getInstance();
        User u = findObject(vo.getHandle());
        u.setCountry(vo.getCountry());
        u.setEmail(vo.getEmail());
        u.setFirstName(vo.getFirstName());
        u.setInstitution(vo.getInstitution());
        u.setLastName(vo.getLastName());
        u.setPassword(vo.getPassword());
        u.setTeam(vo.getTeam());
        updateObject(u);
    }

    public void updateObject(User u) throws Exception {
        uc = getInstance();
        try {
            uc.edit(u);
        } catch (Exception e) {
            System.out.println("EXCEPTION: " + e.getMessage());
            if (e instanceof NonexistentEntityException) {
                throw new NonExistentObjectException();
            }
            throw new DatabaseException("UserService.update Operation");
        }
    }

    public void delete(VOUser vo) throws Exception {
        uc = getInstance();
        try {
            uc.destroy(vo.getIdUser());
        } catch (Exception e) {
            if (e instanceof NonexistentEntityException) {
                throw new NonExistentObjectException();
            }
            throw new DatabaseException("UserService.delete Operation");
        }
    }

    public ArrayList<VOUser> findAll(EnumSearchParameter parameter, String value) throws Exception {
        uc = getInstance();
        if (parameter == EnumSearchParameter.CONTEST) {
            try {
                cs = getContestService();
                Contest c = cs.findObject(value);
                List<User> l = c.getUserList();
                if (l == null) {
                    return null;
                }
                ArrayList<VOUser> ret = new ArrayList<VOUser>();
                for (User u : l) {
                    ret.add(u.getVO());
                }
                return ret;
            } catch (Exception e) {
                throw e;
            }
        } else {
            try {
                ArrayList<VOUser> ret = new ArrayList<VOUser>();
                List<User> l = uc.findAll(parameter, value);
                for (User u : l) {
                    ret.add(u.getVO());
                }

                return ret;
            } catch (Exception e) {
                if (e instanceof NonexistentEntityException) {
                    throw new NonExistentObjectException("A Set of Users With the Given Parameters");
                }
                throw new DatabaseException("UserService.findAll");
            }
        }

    }

    public ArrayList<VOUser> findAll() throws Exception {
        uc = getInstance();
        try {
            ArrayList<VOUser> ret = new ArrayList<VOUser>();
            List<User> l = uc.findUserEntities();
            for (User u : l) {
                ret.add(u.getVO());
            }
            return ret;
        } catch (Exception e) {
            if (e instanceof NonexistentEntityException) {
                throw new NonExistentObjectException();
            }
            throw new DatabaseException();
        }
    }

    public boolean isUserInContest(String handle, String contestCode) throws Exception {
        try {
            ArrayList<VOUser> l = findAll(EnumSearchParameter.CONTEST, contestCode);
            for(VOUser v : l)
                if(v.getHandle().compareTo(handle)==0)
                    return true;
            return false;
        } catch (Exception e) {
            throw e;
        }
    }
}
